iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
0
DevOps

從開源雲到邊緣運算系列 第 13

[Day 13]KubeEdge 部屬 - Pod 相依/互斥 派送

  • 分享至 

  • xImage
  •  

當叢集裡有很多node及pod時,如果想把相同或是相關的服務部屬到同一個node上時該怎麼做呢?
在這裡Pod元件提供了親和性(Affinity)屬性,當然對Deployment也適用,可將服務部屬到有相關標籤的服務所在node上,當然也提供了反親和性(Anti-Affinity),可以避免將把相同的服務部屬到同一個node上,那麼就讓我們來看看要如何實做吧!


Pod Affinity hardMode

※Pod 環境必需(完全)滿足 Pod 相依/互斥配置才可進行派送,否則將創建失敗
※podAffinity 設定為參考 Pod 部署,則 podAntiAffinity 禁止與參考 Pod 部署

  1. 部屬一個Pod到任一Nodemysql.yaml
kubectl apply -f mysql.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql-1
  labels:
    app: mysql
spec:
  containers:
  - image: mysql:5.6
    name: mysql
    env:
    # Use secret in real usage
    - name: MYSQL_ROOT_PASSWORD
      value: password
  1. 查看 Pod 派送到的Node
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071SJZ4gbyylC.png

  1. 確認 Node 的 TopologyKey (Labels) 狀態
kubectl get node --show-labels

https://ithelp.ithome.com.tw/upload/images/20190927/20121071p6d1wozbNx.png

※Pod affinity 擁有 Node domain (Label) 的分別,需指定 topologyKey (domain)
※參考 kubectl get node --show-labels 的資料

  1. 撰寫 相依於 mysql & mongodb 的兩個服務 yaml 檔案nginx-mysql.yaml&nginx-mongodb.yaml

    • 使用 affinity 指定使用 Pod affinity (存在 pod Anti-affinity 防護機制 互斥方案)
    • 使用 requiredDuringSchedulingIgnoredDuringExecution 選用需求符合配置
     apiVersion: v1
     kind: Pod
     metadata:
       name: nginx-mysql
       labels:
         app: nginx
     spec:
       affinity:
         podAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
           - labelSelector:
               matchExpressions:
               - key: app
                 operator: In
                 values:
                 - mysql
             topologyKey: name
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80
           hostPort: 80
    
     apiVersion: v1
     kind: Pod
     metadata:
       name: nginx-mongodb
       labels:
         app: nginx
     spec:
       affinity:
         podAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
           - labelSelector:
               matchExpressions:
               - key: app
                 operator: In
                 values:
                 - mongodb
             topologyKey: name
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80
           hostPort: 80
    

    ※附註說明

    • LabelSelector 設定選擇規則方案(可擁有多個設置,多個選擇方案間相互獨立)
    • matchExpressions 可使用多層匹配(Pod 會在所有需同時滿足時進行執行派送與建立)
    • key 等同於 Node Label Name
    • topologyKey 對於 Node 集群 domain 的選擇
    • operator 提供多種篩選機制
      In:指定 values 的值存在 Label 列表中
      NotIn:指定 values 的值不存在 Label 列表中
      Exists:指定的 Label 存在 (不考慮 values)
      DoesNotExist: 指定的 Label 不存在
      Gt:Label 對應的值大於 values (字串比對)
      Lt:Label 對應的值小於 values (字串比對)
  2. 部屬相依於 mysql & mongodb 的兩個服務 yaml 檔案nginx-mysql.yaml&nginx-mongodb.yaml

kubectl apply -f nginx-mysql.yaml
kubectl apply -f nginx-mongodb.yaml
  1. 查看服務部屬狀態
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071DMUreMt9xU.png
https://ithelp.ithome.com.tw/upload/images/20190927/20121071AdHai0uvNy.png
因無法找到 Pod affinity 參考 Pod 的服務 Labels,Pod 無法進行派送與啟動

Pod Anti-Affinity hardMode

  1. 撰寫服務 yaml 檔案nginx-anti-affinity.yaml
    • 使用 affinity 指定使用 Pod anti-affinity
    • 防護 Pod 共用 Node 機制 (互斥方案)
apiVersion: v1
kind: Pod
metadata:
  name: nginx-anti
  labels:
    app: nginx
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - mysql
        topologyKey: name
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80
      hostPort: 80
  1. 派送服務 yaml 檔
kubectl apply -f nginx-anti-affinity.yaml
  1. 查看服務部屬狀態
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071lMO6dr4efP.png


Pod Affinity softMode

※Pod 參考需求環境派送,若無法匹配則尋找最低負載 Node 部屬 Pod
※podAffinity 設定為參考 Pod 部署,則 podAntiAffinity 禁止與參考 Pod 部署

  1. 部屬一個Pod到任一Nodemysql.yaml
kubectl apply -f mysql.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql-1
  labels:
    app: mysql
spec:
  containers:
  - image: mysql:5.6
    name: mysql
    env:
    # Use secret in real usage
    - name: MYSQL_ROOT_PASSWORD
      value: password
  1. 查看 Pod 派送到的Node
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071SJZ4gbyylC.png

  1. 確認 Node 的 TopologyKey (Labels) 狀態
kubectl get node --show-labels

https://ithelp.ithome.com.tw/upload/images/20190927/20121071p6d1wozbNx.png

  1. 撰寫 相依於 mysql & mongodb 的兩個服務 yaml 檔案nginx-mysql-soft.yaml&nginx-mongodb-soft.yaml

    • 使用 affinity 指定使用 Pod affinity (存在 pod Anti-affinity 防護機制 互斥方案)
    • 使用 preferredDuringSchedulingIgnoredDuringExecution 選用需參考符合配置
     apiVersion: v1
     kind: Pod
     metadata:
       name: nginx-mysql-soft
       labels:
         app: nginx
     spec:
       affinity:
         podAffinity:
           preferredDuringSchedulingIgnoredDuringExecution:
           - weight: 1
             podAffinityTerm:
               labelSelector:
                 matchExpressions:
                 - key: app
                   operator: In
                   values:
                   - mysql
               topologyKey: name
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80
           hostPort: 80
    
    
     apiVersion: v1
     kind: Pod
     metadata:
       name: nginx-mongodb-soft
       labels:
         app: nginx
     spec:
       affinity:
         podAffinity:
           preferredDuringSchedulingIgnoredDuringExecution:
           - weight: 1
             podAffinityTerm:
               labelSelector:
                 matchExpressions:
                 - key: app
                   operator: In
                   values:
                   - mongodb
               topologyKey: name
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80
           hostPort: 80
    

    ※附註說明

    • weight 為參考方案設計部屬權重值(優先派送 Pod 參考規則對於 Node 總評分較高者)
    • podSelectorTerms 設定選擇規則方案(可擁有多個設置,多個選擇方案間相互獨立)
    • LabelSelector 設定選擇規則方案(可擁有多個設置,以 TopologyKey 局域為參考)
    • matchExpressions 可使用多層匹配(Pod 會在所有需同時滿足時進行執行派送與建立)
    • key 等同於 Node Label Name
    • topologyKey 對於 Node 集群 domain 的選擇
    • operator 提供多種篩選機制
      In:指定 values 的值存在 Label 列表中
      NotIn:指定 values 的值不存在 Label 列表中
      Exists:指定的 Label 存在 (不考慮 values)
      DoesNotExist: 指定的 Label 不存在
      Gt:Label 對應的值大於 values (字串比對)
      Lt:Label 對應的值小於 values (字串比對)
  2. 派送服務 yaml 檔

kubectl apply -f nginx-mysql-soft.yaml
kubectl apply -f nginx-mongodb-soft.yaml
  1. 查看部屬服務狀態
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071QvfbAQTWDR.png

※若參考 Pod 的服務 Labels 無法對應,則尋找負載較低的 Node 進行派送與啟動

Pod Anti-Affinity softMode

  1. 撰寫與部屬 一個 Replicaset 為 2的 mysql 服務 Deployment yaml 檔案mysql-deployment.yaml
kubectl apply -f mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
          # Use secret in real usage
        - name: MYSQL_ROOT_PASSWORD
          value: password

  1. 確認每一個 Node 上面皆運行 mysql 資料庫服務
kubectl get deploy -o wide

kubectl get pod -o wide

kubectl get rs

https://ithelp.ithome.com.tw/upload/images/20190927/201210710XqX7DpddS.png

  1. 撰寫一個服務 yaml 檔nginx-anti-affinity-soft.yaml

    • 使用 affinity 指定使用 Pod anti-affinity
    • 防護 Pod 共用 Node 機制 (互斥方案)
     apiVersion: v1
     kind: Pod
     metadata:
       name: nginx-anti-soft
       labels:
         app: nginx
     spec:
       affinity:
         podAntiAffinity:
           preferredDuringSchedulingIgnoredDuringExecution:
           - weight: 1
             podAffinityTerm:
               labelSelector:
                 matchExpressions:
                 - key: app
                   operator: In
                   values:
                   - mysql
               topologyKey: name
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80
           hostPort: 80
    
  2. 派送服務互斥 mysql 服務

kubectl apply -f nginx-anti-affinity-soft.yaml
  1. 查看服務部屬狀態
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071zOLvQBFVyf.png
所有 Node 皆有 mysql Pod 服務,則尋找負載較低的 Node 進行派送與啟動

node 和 pod Affinity hardMode

※測試方案 : 將node Affinity 的 hardMode和pod Affinity 的 hardMode同時配置並執行派送

  1. 查看目前node上Labels
kubectl get node --show-labels

https://ithelp.ithome.com.tw/upload/images/20190927/20121071p6d1wozbNx.png

  1. 查看目前在node上pod
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071NGFB6nCHR2.png

  1. 撰寫服務 yaml 檔nginx-mysql-node-pod-affinity-hard.yaml&nginx-mongodb-node-pod-affinity-hard.yaml
    • 使用 nodeAffinity 和 podAffinity進行部屬測試
    • 使用 requiredDuringSchedulingIgnoredDuringExecution 選用需求符合配置
     apiVersion: v1
     kind: Pod
     metadata:
       name: nginx-mysql-node-pod-affinity-hard
       labels:
         app: nginx
     spec:
       affinity:
         nodeAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
             nodeSelectorTerms:
             - matchExpressions:
               - key: disktype
                 operator: In
                 values:
                 - hdd
         podAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
           - labelSelector:
              matchExpressions:
               - key: app
                 operator: In
                 values:
                 - mysql
             topologyKey: name
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80
           hostPort: 80
    
     apiVersion: v1
     kind: Pod
     metadata:
       name: nginx-mongodb-node-pod-affinity-hard
       labels:
         app: nginx
     spec:
       affinity:
         nodeAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
             nodeSelectorTerms:
             - matchExpressions:
               - key: disktype
                 operator: In
                 values:
                 - hdd
         podAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
           - labelSelector:
              matchExpressions:
               - key: app
                 operator: In
                 values:
                 - mongodb
             topologyKey: name
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80
           hostPort: 80
    
    
  2. 派送服務 yaml檔
kubectl apply -f nginx-mysql-node-pod-affinity-hard.yaml
kubectl apply -f nginx-mongodb-node-pod-affinity-hard.yaml
  1. 查看服務部屬狀態
kubectl get pod -o wide

https://ithelp.ithome.com.tw/upload/images/20190927/20121071Jtufi1Pdv5.png
成功派送 Pod 至符合規定配置的 Node
https://ithelp.ithome.com.tw/upload/images/20190927/20121071T2iuur0iCO.png
因無法找到匹配的需求設置,Pod 無法進行派送與啟動


上一篇
[Day 12]KubeEdge 部屬 - Pod 指定 Node 派送
下一篇
[Day 14]K3s 介紹
系列文
從開源雲到邊緣運算30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言